#include "stdafx.h"
#include "BigInt.h"

using namespace System;
using namespace System::Text;
using namespace System::Collections::Generic;
using namespace Microsoft::VisualStudio::TestTools::UnitTesting;
using namespace APIAL;

namespace BigIntUnitTest
{
	[TestClass]
	public ref class BitwiseUnitTest
	{
	private:
		TestContext^ testContextInstance;
        static BigInt *op1;
        static BigInt *op2;
        static BigInt *res;
        static BigInt *not;


	public: 
		/// <summary>
		///Gets or sets the test context which provides
		///information about and functionality for the current test run.
		///</summary>
		property Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ TestContext
		{
			Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ get()
			{
				return testContextInstance;
			}
			System::Void set(Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ value)
			{
				testContextInstance = value;
			}
		};

		#pragma region Additional test attributes
		//
		//You can use the following additional attributes as you write your tests:
		//
		//Use ClassInitialize to run code before running the first test in the class
		[ClassInitialize()]
		static void MyClassInitialize(Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ testContext) {
			op1 = new BigInt(20, 32);
			op2 = new BigInt(20, 32);
			not = new BigInt(20, 32);
			res = new BigInt(20, 32);
        };
		
		//Use ClassCleanup to run code after all tests in a class have run
		[ClassCleanup()]
		static void MyClassCleanup() {
            delete op1;
            delete op2;
            delete res;
            delete not;
        };
		//
		//Use TestInitialize to run code before running each test
		//[TestInitialize()]
		//void MyTestInitialize() {
  //      };
		//
		//Use TestCleanup to run code after each test has run
		//[TestCleanup()]
		//void MyTestCleanup() {
  //      };
		////
		#pragma endregion 

        // Basic equality tests
		[TestMethod]
		void TestAndEquality1()
		{
            op1->chunks[0] = 0x0f0f;
            op1->chunks[1] = 0xabcd;
            op1->chunks[2] = 0x12345678;
            op1->chunks[3] = 0x12345672;
            op1->chunks[4] = 0xdea5673;
            op1->chunks[5] = 0x0;

            op1->size = 6;
            op1->positive = true;

            op2->chunks[0] = 0x0f0f;
            op2->chunks[1] = 0xabcd;
            op2->chunks[2] = 0xabcdef11;
            op2->chunks[3] = 0x12cdec20;
            op2->chunks[4] = 0x1239ceaf;
            op2->chunks[5] = 0xabcdef12;
            op2->chunks[6] = 0x297653bc;
            op2->chunks[7] = 0xdafe2a38;

            op2->size = 8;
            op2->positive = true;

            And(op1, op2, res);
            Assert::AreEqual<BigInt::chunkType>(0x0f0f & 0x0f0f, res->chunks[0]);
            Assert::AreEqual<BigInt::chunkType>(0xabcd & 0xabcd, res->chunks[1]);
            Assert::AreEqual<BigInt::chunkType>(0x12345678 & 0xabcdef11, res->chunks[2]);
            Assert::AreEqual<BigInt::chunkType>(0x12345672 & 0x12cdec20, res->chunks[3]);
            
            Assert::AreEqual<BigInt::chunkType>(0xdea5673 & 0x1239ceaf, res->chunks[4]);
            //Assert::AreEqual<BigInt::chunkType>(0x123caa10 & 0xabcdef12, res->chunks[5]);
            //Assert::AreEqual<BigInt::chunkType>(0 & 0x297653bc, res->chunks[6]);
            //Assert::AreEqual<BigInt::chunkType>(0 & 0xdafe2a38, res->chunks[7]);

		};

        [TestMethod]
        void TestAndEquality2()
        {
            op1->ParseHexadecimalString("12312345612334131234214abcdef123456789abcdef123456789abcdef123456789abcdef123456789", true);
            op2->ParseHexadecimalString("12312345612334131234214abcdef123456789abcdef123456789abcdef123456789abcdef123456789", true);
            //op1->parseBinaryString("1111", true);
            //op2->parseBinaryString("0000", true);

            And(op1, op2, res);
            Assert::AreEqual<String^>("12312345612334131234214ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789", gcnew String(PrintMagnitudeHexadecimal(res).c_str()));
            Assert::AreEqual(op1->size, res->size);

            res->clear();
            op2->ParseHexadecimalString("0", true);

            And(op1, op2, res);
            Assert::AreEqual<String^>("0", gcnew String(PrintMagnitudeHexadecimal(res).c_str()));
            Assert::AreEqual(op2->size, res->size);

            res->clear();
            op2->ParseHexadecimalString("56789", true);

            And(op1, op2, res);
            Assert::AreEqual<String^>("56789", gcnew String(PrintMagnitudeHexadecimal(res).c_str()));
            Assert::AreEqual(op2->size, res->size);


        };

        // Test alias
        [TestMethod]
        void TestAndAlias1()
        {
            op2->chunks[0] = 0x0f0f;
            op2->chunks[1] = 0xabcd;
            op2->chunks[2] = 0xabcdef11;
            op2->chunks[3] = 0x12cdec20;
            op2->chunks[4] = 0x1239ceaf;
            op2->chunks[5] = 0xabcdef12;
            op2->chunks[6] = 0x297653bc;
            op2->chunks[7] = 0xdafe2a38;

            op2->size = 8;
            op2->positive = true;

            And(op2, op2, res);
            Assert::AreEqual<BigInt::chunkType>(0x0f0f & 0x0f0f, res->chunks[0]);
            Assert::AreEqual<BigInt::chunkType>(0xabcd & 0xabcd, res->chunks[1]);
            Assert::AreEqual<BigInt::chunkType>(0xabcdef11 & 0xabcdef11, res->chunks[2]);
            Assert::AreEqual<BigInt::chunkType>(0x12cdec20 & 0x12cdec20, res->chunks[3]);

            Assert::AreEqual<BigInt::chunkType>(0x1239ceaf & 0x1239ceaf, res->chunks[4]);
            Assert::AreEqual<BigInt::chunkType>(0xabcdef12 & 0xabcdef12, res->chunks[5]);
            Assert::AreEqual<BigInt::chunkType>(0x297653bc & 0x297653bc, res->chunks[6]);
            Assert::AreEqual<BigInt::chunkType>(0xdafe2a38 & 0xdafe2a38, res->chunks[7]);

        };

        [TestMethod]
        void TestAndAlias2()
        {
            op1->chunks[0] = 0x0f0f;
            op1->chunks[1] = 0xabcd;
            op1->chunks[2] = 0x12345678;
            op1->chunks[3] = 0x12345672;
            op1->chunks[4] = 0xdea5673;
            op1->chunks[5] = 0x0;

            op1->size = 6;
            op1->positive = true;

            op2->chunks[0] = 0x0f0f;
            op2->chunks[1] = 0xabcd;
            op2->chunks[2] = 0xabcdef11;
            op2->chunks[3] = 0x12cdec20;
            op2->chunks[4] = 0x1239ceaf;
            op2->chunks[5] = 0xabcdef12;
            op2->chunks[6] = 0x297653bc;
            op2->chunks[7] = 0xdafe2a38;

            op2->size = 8;
            op2->positive = true;

            And(op1, op2, op2);
            
            Assert::AreEqual<BigInt::chunkType>(0x0f0f & 0x0f0f, op2->chunks[0]);
            Assert::AreEqual<BigInt::chunkType>(0xabcd & 0xabcd, op2->chunks[1]);
            Assert::AreEqual<BigInt::chunkType>(0x12345678 & 0xabcdef11, op2->chunks[2]);
            Assert::AreEqual<BigInt::chunkType>(0x12345672 & 0x12cdec20, op2->chunks[3]);

            Assert::AreEqual<BigInt::chunkType>(0xdea5673 & 0x1239ceaf, op2->chunks[4]);

        };

		[TestMethod]
		void testAndTrim() {
			op1->chunks[0] = 0x0F;
			op1->chunks[1] = 0x0A;
			op1->size = 2;

			op2->chunks[0] = 0x0F;
			op2->chunks[1] = 0x05;
			op2->size = 2;

			// Set bits such that the result final chunk is 0
			Assert::AreNotEqual<BigInt::chunkType>(0, op1->chunks[0]&op2->chunks[0]);
			Assert::AreEqual<BigInt::chunkType>(0, op1->chunks[1]&op2->chunks[1]);

			// Perform And operation
			And(op1, op2, res);
			Assert::AreEqual<int>(1, res->size);
			Assert::AreEqual<BigInt::chunkType>(0x0F&0x0F, res->chunks[0]);
			Assert::AreEqual<BigInt::chunkType>(0, res->chunks[1]);
		}

        [TestMethod]
        void TestOREquality1()
        {
            op1->chunks[0] = 0x0f0f;
            op1->chunks[1] = 0xabcd;
            op1->chunks[2] = 0x12345678;
            op1->chunks[3] = 0x12345672;
            op1->chunks[4] = 0xdea5673;
            op1->chunks[5] = 0x123caa10;

            op1->size = 6;
            op1->positive = true;

            op2->chunks[0] = 0x0f0f;
            op2->chunks[1] = 0xabcd;
            op2->chunks[2] = 0xabcdef11;
            op2->chunks[3] = 0x12cdec20;
            op2->chunks[4] = 0x1239ceaf;
            op2->chunks[5] = 0xabcdef12;
            op2->chunks[6] = 0x297653bc;
            op2->chunks[7] = 0xdafe2a38;

            op2->size = 8;
            op2->positive = true;

            Or(op1, op2, res);
            Assert::AreEqual<BigInt::chunkType>(0x0f0f | 0x0f0f, res->chunks[0]);
            Assert::AreEqual<BigInt::chunkType>(0xabcd | 0xabcd, res->chunks[1]);
            Assert::AreEqual<BigInt::chunkType>(0x12345678 | 0xabcdef11, res->chunks[2]);
            Assert::AreEqual<BigInt::chunkType>(0x12345672 | 0x12cdec20, res->chunks[3]);

            Assert::AreEqual<BigInt::chunkType>(0xdea5673 | 0x1239ceaf, res->chunks[4]);
            Assert::AreEqual<BigInt::chunkType>(0x123caa10 | 0xabcdef12, res->chunks[5]);
            Assert::AreEqual<BigInt::chunkType>(0 | 0x297653bc, res->chunks[6]);
            Assert::AreEqual<BigInt::chunkType>(0 | 0xdafe2a38, res->chunks[7]);
        };

        [TestMethod]
        void TestOrEquality2()
        {
            op1->ParseHexadecimalString("12312345612334131234214abcdef123456789abcdef123456789abcdef123456789abcdef123456789", true);
            op2->ParseHexadecimalString("12312345612334131234214abcdef123456789abcdef123456789abcdef123456789abcdef123456789", true);
            
            Or(op1, op2, res);
            Assert::AreEqual<String^>("12312345612334131234214ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789", gcnew String(PrintMagnitudeHexadecimal(res).c_str()));
            Assert::AreEqual(op1->size, res->size);

            res->clear();
            op2->ParseHexadecimalString("0", true);

            Or(op1, op2, res);
            Assert::AreEqual<String^>("12312345612334131234214ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789", gcnew String(PrintMagnitudeHexadecimal(res).c_str()));
            Assert::AreEqual(op1->size, res->size);

            res->clear();
            op2->ParseHexadecimalString("56789", true);

            Or(op1, op2, res);
            Assert::AreEqual<String^>("12312345612334131234214ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789", gcnew String(PrintMagnitudeHexadecimal(res).c_str()));
            Assert::AreEqual(op1->size, res->size);

        }
        
        [TestMethod]
        void TestOrAlias1()
        {
            op2->chunks[0] = 0x0f0f;
            op2->chunks[1] = 0xabcd;
            op2->chunks[2] = 0xabcdef11;
            op2->chunks[3] = 0x12cdec20;
            op2->chunks[4] = 0x1239ceaf;
            op2->chunks[5] = 0xabcdef12;
            op2->chunks[6] = 0x297653bc;
            op2->chunks[7] = 0xdafe2a38;

            op2->size = 8;
            op2->positive = true;

            Or(op2, op2, res);
            Assert::AreEqual<BigInt::chunkType>(0x0f0f | 0x0f0f, res->chunks[0]);
            Assert::AreEqual<BigInt::chunkType>(0xabcd | 0xabcd, res->chunks[1]);
            Assert::AreEqual<BigInt::chunkType>(0xabcdef11 | 0xabcdef11, res->chunks[2]);
            Assert::AreEqual<BigInt::chunkType>(0x12cdec20 | 0x12cdec20, res->chunks[3]);

            Assert::AreEqual<BigInt::chunkType>(0x1239ceaf | 0x1239ceaf, res->chunks[4]);
            Assert::AreEqual<BigInt::chunkType>(0xabcdef12 | 0xabcdef12, res->chunks[5]);
            Assert::AreEqual<BigInt::chunkType>(0x297653bc | 0x297653bc, res->chunks[6]);
            Assert::AreEqual<BigInt::chunkType>(0xdafe2a38 | 0xdafe2a38, res->chunks[7]);

        };

        [TestMethod]
        void TestOrAlias2()
        {
            op1->chunks[0] = 0x0f0f;
            op1->chunks[1] = 0xabcd;
            op1->chunks[2] = 0x12345678;
            op1->chunks[3] = 0x12345672;
            op1->chunks[4] = 0xdea5673;
            op1->chunks[5] = 0x123caa10;

            op1->size = 5;
            op1->positive = true;

            op2->chunks[0] = 0x0f0f;
            op2->chunks[1] = 0xabcd;
            op2->chunks[2] = 0xabcdef11;
            op2->chunks[3] = 0x12cdec20;
            op2->chunks[4] = 0x1239ceaf;
            op2->chunks[5] = 0xabcdef12;
            op2->chunks[6] = 0x297653bc;
            op2->chunks[7] = 0xdafe2a38;

            op2->size = 8;
            op2->positive = true;

            Or(op1, op2, op1);
            Assert::AreEqual<BigInt::chunkType>(0x0f0f | 0x0f0f, op1->chunks[0]);
            Assert::AreEqual<BigInt::chunkType>(0xabcd | 0xabcd, op1->chunks[1]);
            Assert::AreEqual<BigInt::chunkType>(0x12345678 | 0xabcdef11, op1->chunks[2]);
            Assert::AreEqual<BigInt::chunkType>(0x12345672 | 0x12cdec20, op1->chunks[3]);

            Assert::AreEqual<BigInt::chunkType>(0xdea5673 | 0x1239ceaf, op1->chunks[4]);
            Assert::AreEqual<BigInt::chunkType>(0 | 0xabcdef12, op1->chunks[5]);
            Assert::AreEqual<BigInt::chunkType>(0 | 0x297653bc, op1->chunks[6]);
            Assert::AreEqual<BigInt::chunkType>(0 | 0xdafe2a38, op1->chunks[7]);
        };

        [TestMethod]
        void TestXOREquality1()
        {
            op1->chunks[0] = 0x0f0f1;
            op1->chunks[1] = 0xabcd1;
            op1->chunks[2] = 0x12345678;
            op1->chunks[3] = 0x12345672;
            op1->chunks[4] = 0xdea5673;
            op1->chunks[5] = 0x123caa10;

            op1->size = 6;
            op1->positive = true;

            op2->chunks[0] = 0x0f0f;
            op2->chunks[1] = 0xabcd;
            op2->chunks[2] = 0xabcdef11;
            op2->chunks[3] = 0x12cdec20;
            op2->chunks[4] = 0x1239ceaf;
            op2->chunks[5] = 0xabcdef12;
            op2->chunks[6] = 0x297653bc;
            op2->chunks[7] = 0xdafe2a38;
            op2->chunks[8] = 0xafe1111;
            op2->chunks[9] = 0x9838;

            op2->size = 10;
            op2->positive = true;

            Xor(op1, op2, res);
            Assert::AreEqual<BigInt::chunkType>(0x0f0f1 ^ 0x0f0f, res->chunks[0]);
            Assert::AreEqual<BigInt::chunkType>(0xabcd1 ^ 0xabcd, res->chunks[1]);
            Assert::AreEqual<BigInt::chunkType>(0x12345678 ^ 0xabcdef11, res->chunks[2]);
            Assert::AreEqual<BigInt::chunkType>(0x12345672 ^ 0x12cdec20, res->chunks[3]);

            Assert::AreEqual<BigInt::chunkType>(0xdea5673 ^ 0x1239ceaf, res->chunks[4]);
            Assert::AreEqual<BigInt::chunkType>(0x123caa10 ^ 0xabcdef12, res->chunks[5]);
            Assert::AreEqual<BigInt::chunkType>(0 ^ 0x297653bc, res->chunks[6]);
            Assert::AreEqual<BigInt::chunkType>(0 ^ 0xdafe2a38, res->chunks[7]);

            Assert::AreEqual<BigInt::chunkType>(0 ^ 0xafe1111, res->chunks[8]);
            Assert::AreEqual<BigInt::chunkType>(0 ^ 0x9838, res->chunks[9]);
        };

        [TestMethod]
        void TestXOREquality2()
        {
            op1->ParseHexadecimalString("12312345612334131234214abcdef123456789abcdef123456789abcdef123456789abcdef123456789", true);
            op2->ParseHexadecimalString("12312345612334131234214abcdef123456789abcdef123456789abcdef123456789abcdef123456789", true);

            Xor(op1, op2, res);
            Assert::AreEqual<String^>("0", gcnew String(PrintMagnitudeHexadecimal(res).c_str()));
            Assert::AreEqual(0, res->size);

            res->clear();
            op2->ParseHexadecimalString("0", true);

            Xor(op1, op2, res);
            Assert::AreEqual<String^>("12312345612334131234214ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789", gcnew String(PrintMagnitudeHexadecimal(res).c_str()));
            //Assert::AreEqual(op1->size, res->size);

            res->clear();
            op2->clear();
            op2->ParseHexadecimalString("456789", true);

            Xor(op1, op2, res);
            Assert::AreEqual<String^>("12312345612334131234214ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF123000000", gcnew String(PrintMagnitudeHexadecimal(res).c_str()));
            //Assert::AreEqual(op1->size, res->size);
        }

        [TestMethod]
        void TestXorAlias1()
        {
            op2->chunks[0] = 0x0f0f;
            op2->chunks[1] = 0xabcd;
            op2->chunks[2] = 0xabcdef11;
            op2->chunks[3] = 0x12cdec20;
            op2->chunks[4] = 0x1239ceaf;
            op2->chunks[5] = 0xabcdef12;
            op2->chunks[6] = 0x297653bc;
            op2->chunks[7] = 0xdafe2a38;

            op2->size = 8;
            op2->positive = true;

			// Perform res = op2^op2 = 0
            Xor(op2, op2, res);

			// Since the result is 0, the size is 0.
			Assert::AreEqual<int>(0, res->size);
        };
        
        [TestMethod]
        void TestXorAlias2()
        {
            op1->chunks[0] = 0x0f0f1;
            op1->chunks[1] = 0xabcd1;
            op1->chunks[2] = 0x12345678;
            op1->chunks[3] = 0x12345672;
            op1->chunks[4] = 0xdea5673;
            op1->chunks[5] = 0x123caa10;

            op1->size = 6;
            op1->positive = true;

            op2->chunks[0] = 0x0f0f;
            op2->chunks[1] = 0xabcd;
            op2->chunks[2] = 0xabcdef11;
            op2->chunks[3] = 0x12cdec20;
            op2->chunks[4] = 0x1239ceaf;
            op2->chunks[5] = 0xabcdef12;
            op2->chunks[6] = 0x297653bc;
            op2->chunks[7] = 0xdafe2a38;
            op2->chunks[8] = 0xafe1111;
            op2->chunks[9] = 0x9838;

            op2->size = 10;
            op2->positive = true;

            Xor(op1, op2, op2);
            Assert::AreEqual<BigInt::chunkType>(0x0f0f1 ^ 0x0f0f, op2->chunks[0]);
            Assert::AreEqual<BigInt::chunkType>(0xabcd1 ^ 0xabcd, op2->chunks[1]);
            Assert::AreEqual<BigInt::chunkType>(0x12345678 ^ 0xabcdef11, op2->chunks[2]);
            Assert::AreEqual<BigInt::chunkType>(0x12345672 ^ 0x12cdec20, op2->chunks[3]);

            Assert::AreEqual<BigInt::chunkType>(0xdea5673 ^ 0x1239ceaf, op2->chunks[4]);
            Assert::AreEqual<BigInt::chunkType>(0x123caa10 ^ 0xabcdef12, op2->chunks[5]);
            Assert::AreEqual<BigInt::chunkType>(0 ^ 0x297653bc, op2->chunks[6]);
            Assert::AreEqual<BigInt::chunkType>(0 ^ 0xdafe2a38, op2->chunks[7]);

            Assert::AreEqual<BigInt::chunkType>(0 ^ 0xafe1111, op2->chunks[8]);
            Assert::AreEqual<BigInt::chunkType>(0 ^ 0x9838, op2->chunks[9]);

        };

		[TestMethod]
		void TestXorTrim() {
			op1->chunks[0] = 0x07;
			op1->chunks[1] = 0x77;
			op1->normalized = true;
			op1->size = 2;
			
			op2->chunks[0] = 0x1;
			op2->chunks[1] = op1->chunks[1];
			op2->normalized = true;
			op2->size = 2;

			// Last chunk should be equal, resulting in a trim
			Assert::AreEqual<BigInt::chunkType>(op1->chunks[1], op2->chunks[1]);
			Assert::AreNotEqual<BigInt::chunkType>(op1->chunks[0], op2->chunks[0]);

			// Perform XOR. 
			Xor(op1, op2, res);
			Assert::AreEqual<int>(1, res->size);
			Assert::AreEqual<BigInt::chunkType>(0x07^0x1, res->chunks[0]);
			Assert::AreEqual<BigInt::chunkType>(0, res->chunks[1]);
		}

        [TestMethod]
        void TestEEEquality1()
        {
            op1->chunks[0] = 0x0f0f;
            op1->chunks[1] = 0xabcd;
            op1->chunks[2] = 0xabcdef11;
            op1->chunks[3] = 0x12cdec20;
            op1->chunks[4] = 0x1239ceaf;
            op1->chunks[5] = 0xabcdef12;
            op1->chunks[6] = 0x297653bc;
            op1->chunks[7] = 0xdafe2a38;
            op1->chunks[8] = 0xafe1111;
            op1->chunks[9] = 0x9838;

            op1->size = 10;
            op1->positive = true;
			op1->normalized = true;

            op2->chunks[0] = 0x0f0f;
            op2->chunks[1] = 0xabcd;
            op2->chunks[2] = 0xabcdef11;
            op2->chunks[3] = 0x12cdec20;
            op2->chunks[4] = 0x1239ceaf;
            op2->chunks[5] = 0xabcdef12;
            op2->chunks[6] = 0x297653bc;
            op2->chunks[7] = 0xdafe2a38;
            op2->chunks[8] = 0xafe1111;
            op2->chunks[9] = 0x9838;

            op2->size = 10;
            op2->positive = true;
			op2->normalized = true;

			// op1 == op2
            Assert::AreEqual(true, Equal(op1, op2));

			// op1 != op2
			op2->chunks[9] = 0x9839;
            Assert::AreEqual(false, Equal(op1, op2));

			// op1.size < op2.size (op1 != op2)
            op2->chunks[9] = 0x9838;
            op1->size--;
            Assert::AreEqual(false, Equal(op1, op2));
        };

		[TestMethod]
		void TestEqualityDifferentSign() {
			op1->chunks[0] = 0x7F;
			op1->normalized = true;
			op1->positive = true;
			op1->size = 1;

			op2->chunks[0] = 0x7F;
			op2->normalized = true;
			op2->positive = true;
			op2->size = 1;

			// Same sign, so equal
			Assert::IsTrue(Equal(op1, op2));
			op1->positive = false;
			op2->positive = false;
			Assert::IsTrue(Equal(op1, op2));

			// Different sign, so not equal
			op1->positive = true;
			op2->positive = false;
			Assert::IsFalse(Equal(op1, op2));
			op1->positive = false;
			op2->positive = true;
			Assert::IsFalse(Equal(op1, op2));
		}

        [TestMethod]
        void TestNot1()
        {
            op2->chunks[0] = 0x0f0f;
            op2->chunks[1] = 0xdafe2a38;
            op2->chunks[2] = 0xabcdef11;
            op2->chunks[3] = 0x12cdec20;

            op2->size = 3;
            op2->positive = true;
			op2->normalized = true;

            Not(op2, res);
			Assert::AreEqual<int>(3, op2->size);
            Assert::AreEqual<BigInt::chunkType>((~0x0f0f)&op2->nonCarryBitsMask, res->chunks[0]);
            Assert::AreEqual<BigInt::chunkType>((~0xdafe2a38)&op2->nonCarryBitsMask, res->chunks[1]);
            Assert::AreEqual<BigInt::chunkType>((~0xabcdef11)&op2->nonCarryBitsMask, res->chunks[2]);
        };

        [TestMethod]
        void TestNotAliasAndTrim()
        {
            op2->chunks[0] = 0x0f0f;
            op2->chunks[1] = 0xabcd;
            op2->chunks[2] = ~0;
            op2->chunks[3] = 0x12cdec20;

            op2->size = 3;
            op2->positive = true;

            Not(op2, op2);
			Assert::AreEqual<int>(2, op2->size);
            Assert::AreEqual<BigInt::chunkType>((~0x0f0f)&op2->nonCarryBitsMask, op2->chunks[0]);
            Assert::AreEqual<BigInt::chunkType>((~0xabcd)&op2->nonCarryBitsMask, op2->chunks[1]);
            Assert::AreEqual<BigInt::chunkType>(0, op2->chunks[2]);
            Assert::AreEqual<BigInt::chunkType>(0x12cdec20, op2->chunks[3]);
        };

        // cases to test: 
        // resize, c
	};
}
